
#ifndef _WMMXIMAGELIB_H_
#define _WMMXIMAGELIB_H_

#ifdef __cplusplus
extern "C" {
#endif

// Alpha:AlphaChannel
// Blend:Src with transparency
// Only:8bit buffer with AlphaChannel only
// Color:one single color value instead of SrcBuffer

#define Blit888 Blit_8u_C4A                                 // RGB24
#define BlitBlend888 BlitBlend_8u_C4A_PreMul                // RGB24 with transparency
#define AlphaBlit888 AlphaBlit_8u_C4A_PreMul                // ARGB32
#define AlphaBlitBlend888 AlphaBlitBlend_8u_C4A_PreMul      // ARGB32 with transparency
#define AlphaOnly888 AlphaOnly_8u_C4A                       // A8
#define AlphaOnlyBlend888 AlphaOnlyBlend_8u_C4A             // A8 with transparency
#define SetColor888 SetColor_8u_C4A                         // no SrcBuffer but Color value instead
#define BlendColor888 BlendColor_8u_C4A                     // no SrcBuffer but Color value with transparency

#define Add888 Add_8u_C4A                                   // additive alpha blend

#define StretchBlitBlend888 StretchBlitBlend888_PreMul
#define StretchAlphaBlit888 StretchAlphaBlit888_PreMul
#define StretchAlphaBlitBlend888 StretchAlphaBlitBlend888_PreMul
//#define StretchAlphaOnlyBlend888 StretchAlphaOnlyBlend888_PreMul

inline int max(int a, int b)
{
    return a>=b ? a:b;
}

inline int min(int a, int b)
{
    return a<=b ? a:b;
}

#ifndef _EVC
inline int abs(int a)
{
    return a>=0 ? a : -a;
}
#endif

struct POSITION
{
    int   x;
    int   y;
};

struct ScanLineList {
    POSITION Left;
    POSITION Right;
};

struct PIXEL
{
    unsigned char    B;
    unsigned char    G;
    unsigned char    R;
    unsigned char    A;
};

struct INVALIDREGION
{
    int                 tx;
    int                 ty;
    int                 bx;
    int                 by;
};

struct INVALIDRECT
{
    int                 x;
    int                 y;
    int                 width;
    int                 height;
};

struct SURFACE
{
    short *    pData;
    int        nPitch;
    int        nWidth;
    int        nHeight;
};

struct IMGREGION
{
    short *    pData;
    unsigned char*    paData;
    int        nPitch;
    int        naPitch;
    int        nWidth;
    int        nHeight;
};

struct IMAGE
{
    unsigned char*     pData;
    int        nWidth;
    int        nHeight;
    int        nPitch;
    int        nImageType;
};

struct IMAGEARRAY
{
    unsigned char**     pData;
    int        nWidth;
    int        nHeight;
    int        nPitch;
    int        nImageType;
    int        nPlaneNum;
    int        nPlaneUsed;
};

struct IMAGES : public IMAGE
{
    IMAGES * pNext;
};

struct ALPHABLITSTRUCT
{
    unsigned char *lpAlpha;
    int iAlpPitch;
    unsigned char *lpSrc;
    int iSrcPitch;
    unsigned char *lpDst;
    int iDstW;
    int iDstH;
    int iDstPitch;
    int AlphaValue;
};

struct _RENDERSTRUCT
{
public:
    unsigned char *pSrc;
    unsigned char *pDst;
    int nSrcPitch;
    int nDstPitch;
    int nWidth;
    int nHeight;
    unsigned int uRenderType;
    int uAlphaValue;
};

struct _RENDERSTRUCTEX : public _RENDERSTRUCT
{
    int nStretchWidth;
    int nStretchHeight;
    unsigned int IntFloatX;
    unsigned int IntFloatY;
    unsigned int RenderStyle;               //0:nearest neighbor, 1:bilinear interpolation
};

struct _WARPPERSP
{
    PIXEL* pSrc;
    PIXEL* pDst;
    unsigned int Src_Pitch;
    unsigned int Dst_Pitch;
    unsigned int SrcH;
    unsigned int DstW;
    unsigned int DstHL;
    unsigned int DstHR;
    unsigned int DstHD16;
    unsigned int SrcXD16;
    unsigned int SrcYD16;

};

struct _WARPPERSPH
{
    PIXEL* pSrc;
    PIXEL* pDst;
    unsigned int Src_Pitch;
    unsigned int Dst_Pitch;
    unsigned int SrcW;
    unsigned int DstH;
    unsigned int DstWT;
    unsigned int DstWD;
    unsigned int DstWD16;
    unsigned int SrcXD16;
    unsigned int SrcYD16;

};

struct _SHEAR
{
    PIXEL* pSrc;
    PIXEL* pDst;
    unsigned int Src_Pitch;
    unsigned int Dst_Pitch;
    unsigned int SrcW;
    unsigned int SrcH;
    unsigned int DstW;
    unsigned int DstH;
    unsigned int SrcXD16;
    unsigned int SrcYD16;
    unsigned int DstSX16;
    unsigned int Dst_SX16;
    unsigned int offset;
};

struct _CURVE
{
    PIXEL* pSrc;
    PIXEL* pDst;
    unsigned int Src_Pitch;
    unsigned int Dst_Pitch;
    unsigned int SrcW;
    unsigned int SrcH;
    unsigned int DstW;
    unsigned int SrcXD16;
    unsigned int DstH;
    unsigned int SrcYD16;
    unsigned int Dst_SX16;
    int*aSampleX16;
    unsigned int InnerWidth;
};

struct _SINWAVE
{
    int* pDst;
    int len;
    int magQ15;
    int freqQ15;
    int phaseQ15;
    int Scale;
};

struct _AALINEINFO
{
    unsigned char* pDst;
    int nPitch;
    int startP;
    int deltaD;
    int s16;
    int d16;
    int inc;
    int color;
};

struct _AAEDGEINFO : public _AALINEINFO
{
    unsigned char* pSrc;
    ScanLineList* scanlinelist;
    int startY;
};

struct _GRADFILL
{
    unsigned char* pDst;
    int nPitch;
    int incx_16;
    int incy_16;
    int x0;
    int y0;
    int* gradientTable;
    int width;
};

struct _POLYFILL
{
    unsigned char* pSrc;
    unsigned char* pDst;
    int nSrcPitch;
    int nDstPitch;
    int startY;
    int height;
    ScanLineList * scanlinelist;
};

inline void SetPixel(int x, int y, int color, IMAGE *img)
{
    int* dst = (int*)img->pData;

    ((char*&)dst)+=img->nPitch*y;
    dst+=x;
    *dst=color;
}

void GradientFillColor(int* gradientTable, int x0, int y0, int vx, int vy, IMAGE *img);
void GradientFillAlpha(unsigned char* gradientTable, int x0, int y0, int vx, int vy, IMAGE *img);
void DrawAALine(int xs,int ys,int xe,int ye, int color, IMAGE * img);
void DrawAAPolygon(POSITION * leftVertexList, int LEdgeNum, POSITION * rightVertexList, int REdgeNum, IMAGE * srcImg, IMAGE * dstImg, int level);
void BresenhamDrawLine(int xs,int ys,int xe,int ye, int color, IMAGE * img);

extern void GradientFill(_GRADFILL & gfill);
extern void FillPolygon(_POLYFILL & pfill);
extern void FillPolygonA(_POLYFILL & pfill);

extern void DrawXMajorLine(_AALINEINFO & aaline);
extern void DrawYMajorLine(_AALINEINFO & aaline);
extern void DrawXMajorLPEdge(_AAEDGEINFO & aaedge);
extern void DrawXMajorLNEdge(_AAEDGEINFO & aaedge);
extern void DrawYMajorLEdge(_AAEDGEINFO & aaedge);
extern void DrawXMajorRPEdge(_AAEDGEINFO & aaedge);
extern void DrawXMajorRNEdge(_AAEDGEINFO & aaedge);
extern void DrawYMajorREdge(_AAEDGEINFO & aaedge);

typedef void(*pAlphaBlendFuction)(_RENDERSTRUCT & renderstruct);

void __stdcall MemCpy_WMMX(unsigned char* pSrc, unsigned char* pDst, int size);
void __stdcall MemSet_WMMX(unsigned char* pDst, unsigned char value, int size);

extern void Blit_8u_C4A(_RENDERSTRUCT & renderstruct);
extern void AlphaBlit_8u_C4A_PreMul(_RENDERSTRUCT & renderstruct);
extern void AlphaBlitBlend_8u_C4A_PreMul(_RENDERSTRUCT & renderstruct);
extern void BlitBlend_8u_C4A_PreMul(_RENDERSTRUCT & renderstruct);
extern void AlphaOnly_8u_C4A(_RENDERSTRUCT & renderstruct);
extern void AlphaOnlyBlend_8u_C4A(_RENDERSTRUCT & renderstruct);
extern void SetColor_8u_C4A(_RENDERSTRUCT & renderstruct);
extern void BlendColor_8u_C4A(_RENDERSTRUCT & renderstruct);
extern void Add_8u_C4A(_RENDERSTRUCT & renderstruct);

extern void StretchBlitBlend888_PreMul(_RENDERSTRUCTEX & renderstruct);
extern void StretchAlphaBlit888_PreMul(_RENDERSTRUCTEX & renderstruct);
extern void StretchAlphaBlitBlend888_PreMul(_RENDERSTRUCTEX & renderstruct);
extern void StretchAlphaOnlyBlend888(_RENDERSTRUCTEX & renderstruct);

extern void ResizeBilinear_8u_P4(IMAGE& Src, IMAGE& Dst, unsigned long xrIntFloat_16, unsigned long yrIntFloat_16);
extern void ResizeBilinear_8u_P3(IMAGE& Src, IMAGE& Dst, unsigned long xrIntFloat_16, unsigned long yrIntFloat_16);
extern void ResizeBilinear_8u_P1(IMAGE& Src, IMAGE& Dst, unsigned long xrIntFloat_16, unsigned long yrIntFloat_16);
extern void ResizeBilinear_8u_C4A(IMAGE& Src, IMAGE& Dst, unsigned long xrIntFloat_16, unsigned long yrIntFloat_16);

extern void RGB888To565WMMX(IMAGE * image, SURFACE * surface);

void RGB888To565(IMAGE &image, SURFACE &surface, INVALIDREGION &rect, int orientation);
extern void RECT888To565(IMAGE * image, SURFACE * surface);
extern void RECT888To565RCW(IMAGE * image, SURFACE * surface);
extern void RECT888To565RCCW(IMAGE * image, SURFACE * surface);
extern void RECT888To565FLIP(IMAGE * image, SURFACE * surface);

void RGB888To666(IMAGE &image, IMAGE &surface, INVALIDREGION &rect, int orientation);
extern void RECT888To666(IMAGE * image, IMAGE * surface);
extern void RECT888To666RCW(IMAGE * image, IMAGE * surface);
extern void RECT888To666RCCW(IMAGE * image, IMAGE * surface);
extern void RECT888To666FLIP(IMAGE * image, IMAGE * surface);

void RotateBlit(IMAGE &image, IMAGE &surface, INVALIDREGION &rect, int orientation);
extern void RECTBLIT(IMAGE * image, IMAGE * surface);
extern void RECTBLITRCW(IMAGE * image, IMAGE * surface);
extern void RECTBLITRCCW(IMAGE * image, IMAGE * surface);
extern void RECTBLITFLIP(IMAGE * image, IMAGE * surface);

extern void AlphaBlit_8u_C4A(_RENDERSTRUCT & renderstruct);
extern void AlphaBlitBlend_8u_C4A(_RENDERSTRUCT & renderstruct);
extern void AlphaBlend_8u_C4A(_RENDERSTRUCT & renderstruct);

extern void StretchBlit888(_RENDERSTRUCTEX & renderstruct);
//extern void StretchBlitBlend888(_RENDERSTRUCTEX & renderstruct);
//extern void StretchAlphaBlit888(_RENDERSTRUCTEX & renderstruct);
//extern void StretchAlphaBlitBlend888(_RENDERSTRUCTEX & renderstruct);
//extern void StretchAlphaOnlyBlend888(_RENDERSTRUCTEX & renderstruct);

void WarpPerspective_8u_C4A(IMAGE& Src, IMAGE& Dst, int nWidth, int nLHeight, int nRHeight);
void WarpPerspectiveH_8u_C4A(IMAGE& Src, IMAGE& Dst, int nWidthT, int nWidthD, int nHeight);
void ShearBilinear_8u_C4A(IMAGE& Src, IMAGE& Dst, int offset);
void CurveBilinear_8u_C4A(IMAGE& Src, IMAGE& Dst, int* aSampleX16, int width);
void AdditiveCurveBilinearV_8u_C4A(IMAGE& Src, IMAGE& Dst, int* aSampleX16, int offset, int width);
void AdditiveCurveBilinearH_8u_C4A(IMAGE& Src, IMAGE& Dst, int* aSampleX16, int offset, int width);

extern void WarpPerspectiveLWMMX(_WARPPERSP & para);
extern void WarpPerspectiveRWMMX(_WARPPERSP & para);
extern void WarpPerspectiveTWMMX(_WARPPERSPH & para);
extern void WarpPerspectiveDWMMX(_WARPPERSPH & para);

extern void ShearBilinearM_8u_C4A(_SHEAR & shear);
extern void ShearBilinearP_8u_C4A(_SHEAR & shear);
extern void CurveBilinearWMMX_8u_C4A(_CURVE & curve);
extern void AdditiveCurveBilinearWMMXV_8u_C4A(_CURVE & curve);

extern void SinWave_32u(_SINWAVE & sinwave);

void WaveSpread(short** pbuf1,short** pbuf2, int width, int height);
void WaveRender(short* buf1,short* buf2,IMAGE& src,IMAGE& dst);
void DitherImage(unsigned char * pData, int width, int height, int Rbit, int Gbit, int Bbit);

#ifdef __cplusplus
}
#endif

#endif

